﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.TeamFoundation.Client;
using System.Security;
using System.Diagnostics;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.IO;
using System.Xml;
using System.Drawing.Drawing2D;

namespace WitAdminTool
{
    public partial class Form1 : Form
    {
        TfsTeamProjectCollection tfsTPC;
        WorkItemStore workitemStore;

        TreeNode mySelectedNode = new TreeNode();


        public Form1()
        {
            InitializeComponent();
            try
            {
                TeamProjectPicker tpp = new TeamProjectPicker();
                if (tpp.ShowDialog() == DialogResult.OK)
                {
                    tfsTPC = tpp.SelectedTeamProjectCollection;

                    workitemStore = (WorkItemStore)tfsTPC.GetService(typeof(WorkItemStore));
                    this.lblCollection.Text = tfsTPC.Uri.AbsoluteUri;

                    InitForm();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                
            }
        }
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            Blend blend = new Blend();
            Rectangle rDisplay = new Rectangle(0, 0, this.Width, this.Height);
            LinearGradientMode lgm = LinearGradientMode.BackwardDiagonal;
            Color gradientColor = Color.DimGray;
            Color backColor = Color.Black;

            using (LinearGradientBrush lgb = new LinearGradientBrush(rDisplay, gradientColor, backColor, lgm))
            {
                if (blend != null)
                {
                    lgb.Blend = blend;
                }
                e.Graphics.FillRectangle(lgb, rDisplay);
            }
        }
        #region Excute Command
        private void ExcuteCommand(string ApplicationArguments)
        {
            try
            {
                string ApplicationPath = "witadmin.exe";

                Process ProcessObj = new Process();

                ProcessObj.StartInfo.FileName = ApplicationPath;
                ProcessObj.StartInfo.Arguments = ApplicationArguments;

                ProcessObj.StartInfo.UseShellExecute = false;
                ProcessObj.StartInfo.CreateNoWindow = true;

                ProcessObj.StartInfo.WindowStyle = ProcessWindowStyle.Normal;

                ProcessObj.StartInfo.RedirectStandardOutput = true;

                ProcessObj.Start();

                ProcessObj.WaitForExit();

                string Result = ProcessObj.StandardOutput.ReadToEnd();

                MessageBox.Show(Result);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #endregion

        #region Initailize
        private void InitForm()
        {
            InitWorkItemTypePage();
        }
        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                TeamProjectPicker tpp = new TeamProjectPicker();
                if (tpp.ShowDialog() == DialogResult.OK)
                {
                    tfsTPC = tpp.SelectedTeamProjectCollection;

                    workitemStore = (WorkItemStore)tfsTPC.GetService(typeof(WorkItemStore));
                    this.lblCollection.Text = tfsTPC.Uri.AbsoluteUri;

                    this.tabControl1.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = this.tabControl1.SelectedIndex;

            this.InitTabPage(index);
        }
        private void InitTabPage(int index)
        {
            switch (index)
            {
                case 0:
                    this.InitWorkItemTypePage();
                    break;
                case 1:
                    this.InitWorkItemPage();
                    break;
                case 2:
                    this.InitFieldPage();
                    break;
                case 3:
                    this.InitLinkTypePage();
                    break;
                case 4:
                    this.InitGloballistPage();
                    break;
                case 5:
                    this.InitCategoryPage();
                    break;
                default:
                    break;
            }
        }
        private void InitWorkItemTypePage()
        {
            this.workitemStore.SyncToCache();
            this.listProject.Items.Clear();
            this.listWit.Items.Clear();
            foreach (Project project in this.workitemStore.Projects)
            {
                this.listProject.Items.Add(project.Name);
            }
            this.txtWitXml.Text = string.Empty;
        }
        private void InitWorkItemPage()
        {
            this.txtWiID.Text = string.Empty;
            
        }
        private void InitFieldPage()
        {
            this.workitemStore.SyncToCache();
            this.listFields.Items.Clear();
            foreach (FieldDefinition fd in this.workitemStore.FieldDefinitions)
            {
                this.listFields.Items.Add(fd.Name + "/" + fd.ReferenceName);
            }
        }
        private void InitLinkTypePage()
        {
            this.workitemStore.SyncToCache();

            WorkItemLinkTypeCollection ltc = this.workitemStore.WorkItemLinkTypes;

            DataTable dtLik = new DataTable();
            dtLik.Columns.Add("Ref Name");
            dtLik.Columns.Add("ForwordEnd Name");
            dtLik.Columns.Add("ReverseEnd Name");
            dtLik.Columns.Add("Topology");
            dtLik.Columns.Add("Activate");


            foreach (WorkItemLinkType lt in ltc)
            {
                string refName = lt.ReferenceName;
                string fn = lt.ForwardEnd.Name;
                string rn = lt.ReverseEnd.Name;
                string topology = lt.LinkTopology.ToString();
                string actYN = lt.IsActive.ToString();

                dtLik.Rows.Add(refName, fn, rn, topology, actYN);
            }

            this.gvLink.DataSource = dtLik;

            this.txtLinkXml.Text = string.Empty;
        }

        private void InitGloballistPage()
        {
            this.workitemStore.SyncToCache();

            this.txtGLXml.Text = string.Empty;

            if (treeView1.Nodes.Count > 0)
            {
                treeView1.Nodes.RemoveAt(0);
            }

            Hourglass(true);

            XmlDocument globalListXmlDoc = this.workitemStore.ExportGlobalLists();

            TreeNode rootNode = new TreeNode("Global List");

            foreach (System.Xml.XmlNode list in globalListXmlDoc.DocumentElement.ChildNodes)
            {

                TreeNode listNode = new TreeNode(list.Attributes["name"].Value);
                listNode.Tag = "Server";

                foreach (System.Xml.XmlNode listItem in list.ChildNodes)
                {
                    TreeNode treeListItem = new TreeNode(listItem.Attributes["value"].Value);
                    listNode.Nodes.Add(treeListItem);
                }

                rootNode.Nodes.Add(listNode);

            }
            rootNode.Expand();
            treeView1.Nodes.Add(rootNode);

            Hourglass(false);
        }
        private void InitCategoryPage()
        {
            this.workitemStore.SyncToCache();
            this.listCateProject.Items.Clear();
            this.txtCateXml.Text = string.Empty;

            foreach (Project project in this.workitemStore.Projects)
            {
                this.listCateProject.Items.Add(project.Name);
            }
        }
       
        #endregion       

        #region Work Item Type
        private void listProject_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.listWit.Items.Clear();
            
            if (listProject.SelectedItem == null)
            {
                return;
            }
            string project = listProject.SelectedItem.ToString();
            foreach (WorkItemType wit in this.workitemStore.Projects[project].WorkItemTypes)
            {
                this.listWit.Items.Add(wit.Name);
            }
        }

        private void btnRenameWit_Click(object sender, EventArgs e)
        {
            if (listProject.SelectedItem == null)
            {
                MessageBox.Show("Select Project");
                return;
            }
            if (listWit.SelectedItem == null)
            {
                MessageBox.Show("Select Work Item Type");
                return;
            }
            if (this.txtNewWitName.Text == string.Empty)
            {
                MessageBox.Show("Input New Work Item Type Name");
                return;
            }
            string command = string.Format(@"renamewitd /collection:{0} /p:""{1}"" /n:""{2}"" /new:""{3}"" /noprompt", this.lblCollection.Text, this.listProject.SelectedItem.ToString(), this.listWit.SelectedItem.ToString(), this.txtNewWitName.Text);

            if (MessageBox.Show("Really Rename Work Item Type?", "Caution", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                this.ExcuteCommand(command);

                this.InitWorkItemTypePage();
            }
        }

        private void btnWitDelete_Click(object sender, EventArgs e)
        {
            // destroywitd 	/collection: /p: /n: /noprompt
            if (listProject.SelectedItem == null)
            {
                MessageBox.Show("Select Project");
                return;
            }
            if (listWit.SelectedItem == null)
            {
                MessageBox.Show("Select Work Item Type");
                return;
            }

            string command = string.Format(@"destroywitd /collection:{0} /p:""{1}"" /n:""{2}"" /noprompt", this.lblCollection.Text, this.listProject.SelectedItem.ToString(), this.listWit.SelectedItem.ToString());

            if (MessageBox.Show("Really Delete Work Item Type?", "Caution", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                this.ExcuteCommand(command);

                this.InitWorkItemTypePage();
            }
        }

        string witXmlFilePath;
        private void btnWitExport_Click(object sender, EventArgs e)
        {
            if (listProject.SelectedItem == null)
            {
                MessageBox.Show("Select Project");
                return;
            }
            if (listWit.SelectedItem == null)
            {
                MessageBox.Show("Select Work Item Type");
                return;
            }
            // exportwitd 	/collection: /p: /n: /f:

            Directory.CreateDirectory("WorkItemType");
            witXmlFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\WorkItemType\\" + this.listWit.SelectedItem.ToString().Replace(" ", string.Empty) + ".xml";
            string command = string.Format(@"exportwitd /collection:{0} /p:""{1}"" /n:""{2}"" /f:""{3}""", this.lblCollection.Text, this.listProject.SelectedItem.ToString(), this.listWit.SelectedItem.ToString(), witXmlFilePath);
            this.ExcuteCommand(command);

            this.txtWitXml.Text = string.Empty;
            // Read File
            StreamReader reader = File.OpenText(witXmlFilePath);
            string input = null;
            while ((input = reader.ReadLine()) != null)
            {
                //Console.WriteLine(input);
                this.txtWitXml.Text += input + @"
";

            }
            reader.Close();
            //this.btnWitImport.Enabled = true;
            //this.InitWorkItemTypePage();
        }

        private void btnWitImport_Click(object sender, EventArgs e)
        {
            // importwitd	/collection: /p: /f:
            // save xml
            if (this.txtWitXml.Text == string.Empty)
            {
                MessageBox.Show("Work Item Type XML is empty");
                return;
            }

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(this.txtWitXml.Text);
            //Save the document to a file.
            doc.Save(witXmlFilePath);

            string command = string.Format(@"importwitd /collection:{0} /p:""{1}"" /f:""{2}""", this.lblCollection.Text, this.listProject.SelectedItem.ToString(), witXmlFilePath);
            this.ExcuteCommand(command);

            //this.btnWitImport.Enabled = false;
            this.InitWorkItemTypePage();
        }
        #endregion

        #region Work Item
        private void btnGetWi_Click(object sender, EventArgs e)
        {
            this.GetWi();
        }

        private void GetWi()
        {
            this.gvWi.DataSource = null;
            WorkItemCollection wic = this.workitemStore.Query("select [system.id], [System.Title], [System.TeamProject], [System.WorkItemType],[System.CreatedDate],[System.CreatedBy], [System.AssignedTo] from workitems");

            DataTable dt = new DataTable();
            dt.Columns.Add("ID");
            dt.Columns.Add("Type");
            dt.Columns.Add("Title");
            dt.Columns.Add("Project");
            dt.Columns.Add("CreatedBy");
            dt.Columns.Add("CreatedDate");
            dt.Columns.Add("AssignedTo");

            foreach (WorkItem wi in wic)
            {
                dt.Rows.Add(wi.Id.ToString(), wi.Type.Name, wi.Title,wi.Project.Name, wi.CreatedBy, wi.CreatedDate.ToString("yyyy-MM-dd"), wi.Fields[CoreField.AssignedTo].Value.ToString());
            }

            this.gvWi.DataSource = dt;
        }

        private void btnDeleteWi_Click(object sender, EventArgs e)
        {
            if (this.txtWiID.Text == string.Empty)
            {
                MessageBox.Show("Input Work Item ID");
                txtWiID.Focus();
                return;
            }

            if (MessageBox.Show("Really Delete Work Item?", "Caution", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                string command = string.Format(@"destroywi /collection:{0} /id:{1} /noprompt", this.lblCollection.Text, this.txtWiID.Text);
                this.ExcuteCommand(command);

                this.GetWi();
            }
        }

        private void btnDeleteWis_Click(object sender, EventArgs e)
        {
            string ids = string.Empty;

            for (int i = 0; i < this.gvWi.Rows.Count; i++)
            {
                if ((bool)this.gvWi.Rows[i].Cells[0].EditedFormattedValue)
                {
                    if (this.gvWi.Rows[i].Cells[1].Value == null || this.gvWi.Rows[i].Cells[1].Value.ToString() == string.Empty)
                    {
                        continue;
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(ids))
                        {
                            ids = this.gvWi.Rows[i].Cells[1].Value.ToString();
                        }
                        else
                        {
                            ids += "," + this.gvWi.Rows[i].Cells[1].Value.ToString();
                        }
                    }
                }
            }

            if (ids == string.Empty)
            {
                MessageBox.Show("Check Work Item(s)");
                return;
            }

            if (MessageBox.Show("Really Delete Work Item(s)?", "Caution", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                string command = string.Format(@"destroywi /collection:{0} /id:{1} /noprompt", this.lblCollection.Text, ids);
                this.ExcuteCommand(command);

                this.GetWi();
            }
        }
        #endregion

        #region Fields
        private void listFields_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.txtFdName.Text = string.Empty;
            this.txtFdRefName.Text = string.Empty;
            this.txtFdType.Text = string.Empty;

            string seletecItem = this.listFields.SelectedItem.ToString();
            if (!string.IsNullOrEmpty(seletecItem))
            {
                string refName = seletecItem.Split('/')[1];

                FieldDefinition fd = this.workitemStore.FieldDefinitions[refName];
                if (fd != null)
                {
                    txtFdName.Text = fd.Name;
                    txtFdRefName.Text = fd.ReferenceName;
                    txtFdType.Text = fd.FieldType.ToString();
                    this.cbbFdReportType.SelectedItem = fd.ReportingAttributes.Type.ToString().ToLower();
                    if (fd.IsIndexed)
                    {
                        this.cbbIndexYN.SelectedItem = "Y";
                        this.btnIndex.Text = "Index Off";
                    }
                    else
                    {
                        this.cbbIndexYN.SelectedItem = "N";
                        this.btnIndex.Text = "Index On";
                    }
                }
            }
        }

        private void btnDeleteFd_Click(object sender, EventArgs e)
        {
            // deletefield	/collection: /n:(referncename) /noprompt
            if (this.listFields.SelectedItem == null)
            {
                MessageBox.Show("Select Field");
                return;
            }


            if (MessageBox.Show("Really Delete Field?", "Caution", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                string command = string.Format(@"deletefield /collection:{0} /n:{1} /noprompt", this.lblCollection.Text, txtFdRefName.Text);
                this.ExcuteCommand(command);
            }

            this.InitFieldPage();
        }

        private void btnChangeFd_Click(object sender, EventArgs e)
        {
            // changefield	/collection: /n:(referncename) /name:(newname) /syncnamechanges:(true/false) /reportingtype:(dimention,detail,measure,none) /reportingformula:(sum) /noprompt
            if (this.listFields.SelectedItem == null)
            {
                MessageBox.Show("Select Field");
                return;
            }

            if (MessageBox.Show("Really Change Field?", "Caution", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                if (string.IsNullOrEmpty(this.cbbFdReportType.SelectedText))
                {
                    string command = string.Format(@"changefield /collection:{0} /n:{1} /name:""{2}"" /noprompt", this.lblCollection.Text, txtFdRefName.Text, this.txtFdName.Text);
                    this.ExcuteCommand(command);
                }
                else
                {
                    string command = string.Format(@"changefield /collection:{0} /n:{1} /name:""{2}"" /reportingtype:{3} /noprompt", this.lblCollection.Text, txtFdRefName.Text, this.txtFdName.Text, this.cbbFdReportType.SelectedText);
                    this.ExcuteCommand(command);
                }
                InitFieldPage();

            }
        }
        private void btnIndex_Click(object sender, EventArgs e)
        {
            if (this.listFields.SelectedItem == null)
            {
                MessageBox.Show("Select Field");
                return;
            }

            if (this.btnIndex.Text == "Index On")
            {
                // indexfield	/collection: /n:(referncename) /index:(on/off)
                string command = string.Format(@"indexfield /collection:{0} /n:{1} /index:{2} ", this.lblCollection.Text, this.txtFdRefName.Text, "on");
                this.ExcuteCommand(command);
                this.InitFieldPage();
            }
            else
            {
                // indexfield	/collection: /n:(referncename) /index:(on/off)
                string command = string.Format(@"indexfield /collection:{0} /n:{1} /index:{2} ", this.lblCollection.Text, this.txtFdRefName.Text, "off");
                this.ExcuteCommand(command);
                this.InitFieldPage();
            }
        }
        #endregion

        #region LinkType
        private void btnDeleteLink_Click(object sender, EventArgs e)
        {
            // /collection: /n:(linktypename,linkrefname) /noprompt
            if (this.gvLink.SelectedRows == null
                || this.gvLink.SelectedRows.Count == 0
                || this.gvLink.SelectedRows[0].Cells[0].Value == null
                || this.gvLink.SelectedRows[0].Cells[0].Value.ToString() == string.Empty
                )
            {
                MessageBox.Show("Select LinkType Row");
                return;
            }

            if (MessageBox.Show("Really Change LinkType?", "Caution", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                string command = string.Format(@"deletelinktype /collection:{0} /n:""{1}"" /noprompt", this.lblCollection.Text, this.gvLink.SelectedRows[0].Cells[0].Value.ToString());
                this.ExcuteCommand(command);
                this.InitLinkTypePage();

            }
        }
        string linkTypeFilePath;
        private void btnExport_Click(object sender, EventArgs e)
        {
            if (this.gvLink.SelectedRows == null
                || this.gvLink.SelectedRows.Count == 0
                || this.gvLink.SelectedRows[0].Cells[0].Value == null
                || this.gvLink.SelectedRows[0].Cells[0].Value.ToString() == string.Empty
                )
            {
                MessageBox.Show("Select LinkType Row");
                return;
            }
            // exportlinktype	/collection: /n:(linktypename,linkrefname) /f:

            Directory.CreateDirectory("LinkType");
            linkTypeFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\LinkType\\" + this.gvLink.SelectedRows[0].Cells[0].Value.ToString().Replace(" ", string.Empty).Replace(".", string.Empty) + ".xml";
            string command = string.Format(@"exportlinktype /collection:{0} /n:""{1}"" /f:""{2}""", this.lblCollection.Text, this.gvLink.SelectedRows[0].Cells[0].Value.ToString(), linkTypeFilePath);
            this.ExcuteCommand(command);

            this.txtLinkXml.Text = string.Empty;
            // Read File
            StreamReader reader = File.OpenText(linkTypeFilePath);
            string input = null;
            while ((input = reader.ReadLine()) != null)
            {
                //Console.WriteLine(input);
                this.txtLinkXml.Text += input + @"
";

            }
            reader.Close();
        }

        private void btnImportLink_Click(object sender, EventArgs e)
        {

            if (this.gvLink.SelectedRows == null
                || this.gvLink.SelectedRows.Count == 0
                || this.gvLink.SelectedRows[0].Cells[0].Value == null
                || this.gvLink.SelectedRows[0].Cells[0].Value.ToString() == string.Empty
                )
            {
                MessageBox.Show("Select LinkType Row");
                return;
            }

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(this.txtLinkXml.Text);
            //Save the document to a file.
            doc.Save(linkTypeFilePath);
            //importlinktype	/collection: /f: 
            string command = string.Format(@"importlinktype /collection:{0} /f:""{1}"" ", this.lblCollection.Text, linkTypeFilePath);
            this.ExcuteCommand(command);

            //this.btnWitImport.Enabled = false;
            this.InitLinkTypePage();
        }

        private void btnDeactLink_Click(object sender, EventArgs e)
        {

            if (this.gvLink.SelectedRows == null
                || this.gvLink.SelectedRows.Count == 0
                || this.gvLink.SelectedRows[0].Cells[0].Value == null
                || this.gvLink.SelectedRows[0].Cells[0].Value.ToString() == string.Empty
                )
            {
                MessageBox.Show("Select LinkType Row");
                return;
            }

            // deactivatelinktype	/collection: /n:
            string command = string.Format(@"deactivatelinktype /collection:{0} /n:""{1}""", this.lblCollection.Text, this.gvLink.SelectedRows[0].Cells[0].Value.ToString());
            this.ExcuteCommand(command);

            this.InitLinkTypePage();
        }

        private void btnReactivateLink_Click(object sender, EventArgs e)
        {
            if (this.gvLink.SelectedRows == null
                || this.gvLink.SelectedRows.Count == 0
                || this.gvLink.SelectedRows[0].Cells[0].Value == null
                || this.gvLink.SelectedRows[0].Cells[0].Value.ToString() == string.Empty
                )
            {
                MessageBox.Show("Select LinkType Row");
                return;
            }

            // reactivatelinktype	/collection: /n:
            string command = string.Format(@"reactivatelinktype /collection:{0} /n:""{1}""", this.lblCollection.Text, this.gvLink.SelectedRows[0].Cells[0].Value.ToString());
            this.ExcuteCommand(command);

            this.InitLinkTypePage();
        }
        #endregion

        #region GlobalList
        private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (e.Label != null)
            {
                if (e.Label.Length > 0)
                {
                    if (mySelectedNode.Parent == treeView1.Nodes[0] && mySelectedNode.Tag == (object)"Server")
                    {
                        e.CancelEdit = true;
                        MessageBox.Show("Cannot rename lists that have been saved to the server.");
                    }
                    else if (e.Label.IndexOfAny(new char[] { '@', ',', '!', '\\' }) == -1)
                    {
                        // Stop editing without canceling the label change.
                        e.Node.EndEdit(false);
                    }
                    else
                    {
                        /* Cancel the label edit action, inform the user, and 
                           place the node in edit mode again. */
                        e.CancelEdit = true;
                        MessageBox.Show("Invalid tree node label.\n" +
                           "The invalid characters are: '@', ',', '!', '\'",
                           "Node Label Edit");
                        e.Node.BeginEdit();
                    }
                }
                else
                {
                    /* Cancel the label edit action, inform the user, and 
                       place the node in edit mode again. */
                    e.CancelEdit = true;
                    MessageBox.Show("Invalid tree node label.\nThe label cannot be blank",
                       "Node Label Edit");
                    e.Node.Parent.Expand();
                    e.Node.Expand();
                    e.Node.BeginEdit();

                }
                this.treeView1.LabelEdit = false;
            }
        }

        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            mySelectedNode = treeView1.GetNodeAt(e.X, e.Y);
        }
        private void NewItem()
        {
            TreeNode targetNode;

            if (mySelectedNode.Parent != null && mySelectedNode.Parent == treeView1.Nodes[0])
            {
                targetNode = mySelectedNode;
            }
            else if (mySelectedNode.Parent != null)
            {
                targetNode = mySelectedNode.Parent;
            }
            else if (mySelectedNode == treeView1.Nodes[0])
            {
                targetNode = mySelectedNode;
            }
            else
            {
                MessageBox.Show("Select a target list");
                return;
            }

            TreeNode newNode = new TreeNode("New Item");

            mySelectedNode = newNode;

            this.treeView1.LabelEdit = true;

            targetNode.Nodes.Add(newNode);
            ExpandParents(newNode);
            newNode.BeginEdit();
        }

        private void ExpandParents(TreeNode node)
        {
            while (node.Parent != null)
            {
                node.Parent.Expand();
                node = node.Parent;
            }

        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {

            if (treeView1.Nodes[0] != mySelectedNode) //Can't delete root node
            {
                if (mySelectedNode.Level == 1)
                {
                    MessageBox.Show("Cannon delete Root Node, Use the Delete Button");
                    return;
                }
                if (mySelectedNode.Parent == treeView1.Nodes[0] && mySelectedNode.Tag == (object)"server")
                {
                    MessageBox.Show("Cannot delete lists that have been saved to the server");
                }
                else
                {
                    treeView1.Nodes.Remove(mySelectedNode);
                }
            }
            else
            {
                MessageBox.Show("Cannot delete the root node");
            }
        }
        private void addToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewItem();
        }

        private void editToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (mySelectedNode != null && mySelectedNode.Parent != null)
            {
                treeView1.SelectedNode = mySelectedNode;
                treeView1.LabelEdit = true;
                if (!mySelectedNode.IsEditing)
                {
                    mySelectedNode.BeginEdit();
                }
            }
            else
            {
                MessageBox.Show("No tree node selected or selected node is a root node\n" +
                   "Editing of root nodes is not allowed", "Invalid selection");
            }
        }
        private XmlDocument CreateXMLDocFromTree()
        {

            XmlDocument doc = new XmlDocument();
            XmlElement rootNode = doc.CreateElement("gl", "GLOBALLISTS", "http://schemas.microsoft.com/VisualStudio/2005/workitemtracking/globallists");


            foreach (TreeNode treeList in treeView1.Nodes[0].Nodes)
            {
                XmlElement listNode = doc.CreateElement("GLOBALLIST");
                XmlAttribute listNodeName = doc.CreateAttribute("name");
                listNodeName.Value = treeList.Text;
                listNode.Attributes.Append(listNodeName);
                foreach (TreeNode treeListItem in treeList.Nodes)
                {
                    XmlElement listItemNode = doc.CreateElement("LISTITEM");
                    XmlAttribute listItemNodeValue = doc.CreateAttribute("value");
                    listItemNodeValue.Value = treeListItem.Text;
                    listItemNode.Attributes.Append(listItemNodeValue);
                    listNode.AppendChild(listItemNode);
                } rootNode.AppendChild(listNode);

            }
            doc.AppendChild(rootNode);
            return doc;
        }

        private void btnGLSave_Click(object sender, EventArgs e)
        {
            Hourglass(true);

            System.Xml.XmlDocument doc = CreateXMLDocFromTree();

            try
            {
                this.workitemStore.ImportGlobalLists(doc.DocumentElement);
                MessageBox.Show("Global List Saved");
            }
            catch (Exception exp)
            {
                MessageBox.Show("Could not save the list. Error:" + exp.ToString());
            }

            Hourglass(false);

            this.InitGloballistPage();
        }

        string globlListFilePath;
        private void btnGLExport_Click(object sender, EventArgs e)
        {
            Directory.CreateDirectory("GlobalList");
            globlListFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\GlobalList\\" + this.workitemStore.TeamProjectCollection.InstanceId.ToString() + ".xml";
            string command = string.Format(@"exportgloballist /collection:{0} /f:""{1}""", this.lblCollection.Text, globlListFilePath);
            this.ExcuteCommand(command);

            this.txtGLXml.Text = string.Empty;
            // Read File
            StreamReader reader = File.OpenText(globlListFilePath);
            string input = null;
            while ((input = reader.ReadLine()) != null)
            {
                //Console.WriteLine(input);
                this.txtGLXml.Text += input + @"
";

            }
            reader.Close();
        }

        private void btnGLImport_Click(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(this.txtGLXml.Text);
            //Save the document to a file.
            doc.Save(globlListFilePath);
            //importlinktype	/collection: /f: 
            string command = string.Format(@"importgloballist /collection:{0} /f:""{1}"" ", this.lblCollection.Text, globlListFilePath);
            this.ExcuteCommand(command);

            //this.btnWitImport.Enabled = false;
            this.InitGloballistPage();
        }

        private void btnGLDelete_Click(object sender, EventArgs e)
        {
            if (this.treeView1.SelectedNode == null)
            {
                MessageBox.Show("Select list's root node");
                return;
            }
            if (this.treeView1.SelectedNode.Level != 1)
            {
                MessageBox.Show("Only you can delete list's root node");
            }
            else
            {
                // destorygloballist	/collection: /n: /noprompt
                string command = string.Format(@"destroygloballist /collection:{0} /n:""{1}"" /noprompt ", this.lblCollection.Text, this.treeView1.SelectedNode.Text);
                this.ExcuteCommand(command);
                this.InitGloballistPage();
            }
        }

        private void Hourglass(bool Show)
        {
            if (Show == true)
            {
                System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
            }
            else
            {
                System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
            }
            return;
        }
        #endregion

        #region Category
        string cateXmlFilePath;
        private void listCateProject_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.listCateProject.SelectedItem == null)
            {
                return;
            }
            string project = listCateProject.SelectedItem.ToString();

            //foreach (Category cate in this.workitemStore.Projects[project].Categories)
            //{
            //    cate.
            //}
        }
        private void btnCateExport_Click(object sender, EventArgs e)
        {
            if (this.listCateProject.SelectedItem == null)
            {
                MessageBox.Show("Select Project");
                return;
            }
            string project = listCateProject.SelectedItem.ToString();

            //exportcategories	/collection: /p:(projectname) /f:

            Directory.CreateDirectory("Category");
            cateXmlFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\Category\\" + project.Replace(" ", string.Empty) + ".xml";
            string command = string.Format(@"exportcategories /collection:{0} /p:""{1}"" /f:{2}", this.lblCollection.Text, project, cateXmlFilePath);
            this.ExcuteCommand(command);

            this.txtCateXml.Text = string.Empty;
            // Read File
            StreamReader reader = File.OpenText(cateXmlFilePath);
            string input = null;
            while ((input = reader.ReadLine()) != null)
            {
                //Console.WriteLine(input);
                this.txtCateXml.Text += input + @"
";

            }
            reader.Close();
        }

        private void btnCateImport_Click(object sender, EventArgs e)
        {
            if (this.listCateProject.SelectedItem == null)
            {
                MessageBox.Show("Select Project");
                return;
            }
            string project = listCateProject.SelectedItem.ToString();

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(this.txtCateXml.Text);
            //Save the document to a file.
            doc.Save(cateXmlFilePath);
            string command = string.Format(@"importcategories /collection:{0} /p:""{1}"" /f:{2}", this.lblCollection.Text, project, cateXmlFilePath);
            this.ExcuteCommand(command);

            this.InitCategoryPage();
        }
        #endregion       
    }
}
